virt_startinfo_addr->shared_info = (shared_info_t *)meminfo->virt_shinfo_addr;
virt_startinfo_addr->pt_base = meminfo->virt_load_addr +
((p->tot_pages - 1) << PAGE_SHIFT);
-
- /* now, this is just temprorary before we switch to pseudo phys
- * addressing. this works only for contiguous chunks of memory!!!
- */
- virt_startinfo_addr->phys_base = p->pg_head << PAGE_SHIFT;
/* Add virtual network interfaces and point to them in startinfo. */
while (meminfo->num_vifs-- > 0) {
(shared_info_t *)virt_shinfo_address;
virt_startinfo_address->pt_base = virt_load_address +
((p->tot_pages - 1) << PAGE_SHIFT);
- virt_startinfo_address->phys_base = p->pg_head << PAGE_SHIFT;
/* Add virtual network interfaces and point to them in startinfo. */
while (params->num_vifs-- > 0) {
* to all domains except DOM0.
*/
#define HYPERVISOR_VIRT_START (0xFC000000UL)
+#ifndef machine_to_phys_mapping
+#define machine_to_phys_mapping ((unsigned long *)HYPERVISOR_VIRT_START)
+#endif
typedef struct trap_info_st
{
typedef struct start_info_st {
unsigned long nr_pages; /* total pages allocated to this domain */
shared_info_t *shared_info; /* start address of shared info struct */
- unsigned long pt_base; /* address of page directory */
- unsigned long phys_base;
+ unsigned long pt_base; /* VIRTUAL address of page directory */
unsigned long mod_start; /* start address of pre-loaded module */
unsigned long mod_len; /* size (bytes) of pre-loaded module */
net_ring_t *net_rings;
/* Offsets in start_info structure */
#define SHARED_INFO 4
-#define MOD_START 16
-#define MOD_LEN 20
+#define MOD_START 12
+#define MOD_LEN 16
startup_32:
cld
shared_info_t *HYPERVISOR_shared_info;
+unsigned long *phys_to_machine_mapping;
+
/*
* Machine setup..
*/
{
unsigned long start_pfn, max_pfn, max_low_pfn;
unsigned long bootmap_size;
+ unsigned long i;
extern void hypervisor_callback(void);
extern void failsafe_callback(void);
{
unsigned long pgde = *pgd++;
if ( !(pgde & 1) ) continue;
- pte = (pgde & PAGE_MASK) - start_info.phys_base;
+ pte = machine_to_phys(pgde & PAGE_MASK);
reserve_bootmem(pte, PAGE_SIZE);
}
}
cur_pgd = init_mm.pgd = (pgd_t *)start_info.pt_base;
+ /* Now initialise the physical->machine mapping table. */
+ phys_to_machine_mapping = alloc_bootmem(max_pfn * sizeof(unsigned long));
+ for ( i = 0; i < max_pfn; i++ )
+ {
+ unsigned long pgde, *ppte;
+ unsigned long pfn = i + (PAGE_OFFSET >> PAGE_SHIFT);
+ pgde = *((unsigned long *)start_info.pt_base + (pfn >> 10));
+ ppte = (unsigned long *)machine_to_phys(pgde & PAGE_MASK) + (pfn&1023);
+ phys_to_machine_mapping[i] =
+ (*(unsigned long *)__va(ppte)) >> PAGE_SHIFT;
+ }
+
#ifdef CONFIG_BLK_DEV_INITRD
if (start_info.mod_start) {
if ((__pa(start_info.mod_start) + start_info.mod_len) <=
printk(" printing eip:\n");
printk("%08lx\n", regs->eip);
page = ((unsigned long *) cur_pgd)[address >> 22];
- printk(KERN_ALERT "*pde = %08lx(%08lx)\n", page, page - start_info.phys_base);
+ printk(KERN_ALERT "*pde=%08lx(%08lx)\n", page, machine_to_phys(page));
if (page & 1) {
page &= PAGE_MASK;
address &= 0x003ff000;
- page -= start_info.phys_base;
+ page = machine_to_phys(page);
page = ((unsigned long *) __va(page))[address >> PAGE_SHIFT];
- printk(KERN_ALERT "*pte = %08lx(%08lx)\n", page,
- page - start_info.phys_base);
+ printk(KERN_ALERT "*pte=%08lx(%08lx)\n", page,
+ machine_to_phys(page));
}
die("Oops", regs, error_code);
bust_spinlocks(0);
pte = update_debug_queue[i].ptep;
if ( pte == NULL ) continue;
update_debug_queue[i].ptep = NULL;
- update.ptr = __pa(pte) + start_info.phys_base;
+ update.ptr = phys_to_machine(__pa(pte));
update.val = update_debug_queue[i].pteval;
HYPERVISOR_pt_update(&update, 1);
}
pgd = pgd_offset_k(va);
pmd = pmd_offset(pgd, va);
pte = pte_offset(pmd, va);
- update.ptr = __pa(pte) + start_info.phys_base;
+ update.ptr = phys_to_machine(__pa(pte));
pteval = *(unsigned long *)pte;
update.val = pteval & ~_PAGE_PRESENT;
HYPERVISOR_pt_update(&update, 1);
#if PT_UPDATE_DEBUG > 0
DEBUG_disallow_pt_read(ptr);
#endif
- update_queue[idx].ptr = ptr + start_info.phys_base;
+ update_queue[idx].ptr = phys_to_machine(ptr);
update_queue[idx].val = val;
increment_index();
}
void queue_l2_entry_update(unsigned long ptr, unsigned long val)
{
- update_queue[idx].ptr = ptr + start_info.phys_base;
+ update_queue[idx].ptr = phys_to_machine(ptr);
update_queue[idx].val = val;
increment_index();
}
void queue_pt_switch(unsigned long ptr)
{
- update_queue[idx].ptr = ptr + start_info.phys_base;
+ update_queue[idx].ptr = phys_to_machine(ptr);
update_queue[idx].ptr |= PGREQ_EXTENDED_COMMAND;
update_queue[idx].val = PGEXT_NEW_BASEPTR;
increment_index();
void queue_pgd_pin(unsigned long ptr)
{
- update_queue[idx].ptr = ptr + start_info.phys_base;
+ update_queue[idx].ptr = phys_to_machine(ptr);
update_queue[idx].ptr |= PGREQ_EXTENDED_COMMAND;
update_queue[idx].val = PGEXT_PIN_L2_TABLE;
increment_index();
void queue_pgd_unpin(unsigned long ptr)
{
- update_queue[idx].ptr = ptr + start_info.phys_base;
+ update_queue[idx].ptr = phys_to_machine(ptr);
update_queue[idx].ptr |= PGREQ_EXTENDED_COMMAND;
update_queue[idx].val = PGEXT_UNPIN_TABLE;
increment_index();
void queue_pte_pin(unsigned long ptr)
{
- update_queue[idx].ptr = ptr + start_info.phys_base;
+ update_queue[idx].ptr = phys_to_machine(ptr);
update_queue[idx].ptr |= PGREQ_EXTENDED_COMMAND;
update_queue[idx].val = PGEXT_PIN_L1_TABLE;
increment_index();
void queue_pte_unpin(unsigned long ptr)
{
- update_queue[idx].ptr = ptr + start_info.phys_base;
+ update_queue[idx].ptr = phys_to_machine(ptr);
update_queue[idx].ptr |= PGREQ_EXTENDED_COMMAND;
update_queue[idx].val = PGEXT_UNPIN_TABLE;
increment_index();
void __init paging_init(void)
{
+ unsigned long zones_size[MAX_NR_ZONES] = {0, 0, 0};
+ unsigned int max_dma, high, low;
+
+ max_dma = virt_to_phys((char *)MAX_DMA_ADDRESS) >> PAGE_SHIFT;
+ low = max_low_pfn;
+ high = highend_pfn;
+
+ if (low < max_dma)
{
- unsigned long zones_size[MAX_NR_ZONES] = {0, 0, 0};
- unsigned int max_dma, high, low;
-
- max_dma = virt_to_phys((char *)MAX_DMA_ADDRESS) >> PAGE_SHIFT;
- low = max_low_pfn;
- high = highend_pfn;
-
- if (low < max_dma)
- zones_size[ZONE_DMA] = low;
- else {
- zones_size[ZONE_DMA] = max_dma;
- zones_size[ZONE_NORMAL] = low - max_dma;
- }
- free_area_init(zones_size);
+ zones_size[ZONE_DMA] = low;
}
- return;
+ else
+ {
+ zones_size[ZONE_DMA] = max_dma;
+ zones_size[ZONE_NORMAL] = low - max_dma;
+ }
+ free_area_init(zones_size);
}
/* arch/xeno/mm/hypervisor.c */
/*
- * NB. ptr values should be fake-physical. 'vals' should be already
- * fully adjusted (ie. for start_info.phys_base).
+ * NB. ptr values should be PHYSICAL, not MACHINE. 'vals' should be already
+ * be MACHINE addresses.
*/
extern unsigned int pt_update_queue_idx;
update_debug_queue[pt_update_queue_idx].line = __LINE__; \
update_debug_queue[pt_update_queue_idx].file = __FILE__; \
printk("L1 %s %d: %08lx (%08lx -> %08lx)\n", __FILE__, __LINE__, \
- (_p)+start_info.phys_base, *(unsigned long *)__va(_p), \
+ phys_to_machine(_p), *(unsigned long *)__va(_p), \
(unsigned long)(_v)); \
queue_l1_entry_update((_p),(_v)); \
})
update_debug_queue[pt_update_queue_idx].line = __LINE__; \
update_debug_queue[pt_update_queue_idx].file = __FILE__; \
printk("L2 %s %d: %08lx (%08lx -> %08lx)\n", __FILE__, __LINE__, \
- (_p)+start_info.phys_base, *(unsigned long *)__va(_p), \
+ phys_to_machine(_p), *(unsigned long *)__va(_p), \
(unsigned long)(_v)); \
queue_l2_entry_update((_p),(_v)); \
})
#define clear_user_page(page, vaddr) clear_page(page)
#define copy_user_page(to, from, vaddr) copy_page(to, from)
+/**** MACHINE <-> PHYSICAL CONVERSION MACROS ****/
+extern unsigned long *phys_to_machine_mapping;
+#define pfn_to_mfn(_pfn) (phys_to_machine_mapping[(_pfn)])
+#define mfn_to_pfn(_mfn) (machine_to_phys_mapping[(_mfn)])
+static inline unsigned long phys_to_machine(unsigned long phys)
+{
+ unsigned long machine = pfn_to_mfn(phys >> PAGE_SHIFT);
+ machine = (machine << PAGE_SHIFT) | (phys & ~PAGE_MASK);
+ return machine;
+}
+static inline unsigned long machine_to_phys(unsigned long machine)
+{
+ unsigned long phys = mfn_to_pfn(machine >> PAGE_SHIFT);
+ phys = (phys << PAGE_SHIFT) | (machine & ~PAGE_MASK);
+ return phys;
+}
+
/*
* These are used to make use of C type-checking..
*/
static inline unsigned long pte_val(pte_t x)
{
unsigned long ret = x.pte_low;
- if ( (ret & 1) ) ret -= start_info.phys_base;
+ if ( (ret & 1) ) ret = machine_to_phys(ret);
return ret;
}
#endif
static inline unsigned long pmd_val(pmd_t x)
{
unsigned long ret = x.pmd;
- if ( (ret & 1) ) ret -= start_info.phys_base;
+ if ( (ret & 1) ) ret = machine_to_phys(ret);
return ret;
}
#define pgd_val(x) ({ BUG(); (unsigned long)0; })
static inline pte_t __pte(unsigned long x)
{
- if ( (x & 1) ) x += start_info.phys_base;
+ if ( (x & 1) ) x = phys_to_machine(x);
return ((pte_t) { (x) });
}
static inline pmd_t __pmd(unsigned long x)
{
- if ( (x & 1) ) x += start_info.phys_base;
+ if ( (x & 1) ) x = phys_to_machine(x);
return ((pmd_t) { (x) });
}
#define __pgd(x) ({ BUG(); (pgprot_t) { 0 }; })